#include "Texture.h"

Texture::Texture()
{
	m_fileCount = 0;
	m_fileName = NULL;
	m_filePath = NULL;
	m_fileConfig = NULL;
}

Texture::Texture(FWuint count, char* path, char* name)
{
	m_fileCount = count;
	m_filePath = new char[strlen(path) + 1];
	strcpy(m_filePath, path);
	m_fileName = new char[strlen(name) + 1];
	strcpy(m_fileName, name);
	m_fileConfig = NULL;

	m_iTargetType = FW_TEXTURE_2D;
}

Texture::~Texture()
{

}

void Texture::SetTargetType(FWint type)
{
	m_iTargetType = type;
}

FWint Texture::Init()
{
	switch (m_iTargetType)
	{
	case FW_TEXTURE_2D:
		return Image2D();
	case FW_TEXTURE_CUBE_MAP:
		return ImageCube();
	default:
		return FW_ERR_TYPE;
	}
}

FWint Texture::Image2D()
{
	char **files = new char*[m_fileCount];
	char* temp = strtok(_strdup(m_fileName), ";");
	int i = 0;
	while (temp != NULL)
	{
		files[i] = temp;
		temp = strtok(NULL, ";");
		i++;
	}

	TBOCount = m_fileCount;
	TBOs = new FWuint[TBOCount];
	glGenTextures(TBOCount, TBOs);

	FWint iWidth, iHeight, iBPP;
	char* src = NULL;
	FWint formatType;

	for (FWuint i = 0; i < TBOCount; i++)
	{
		std::string file = BASE_SRC_PATH + std::string(m_filePath) + std::string(files[i]);
		src = TGAImage::LoadTGA(file.c_str(), &iWidth, &iHeight, &iBPP);
		switch (iBPP)
		{
		case 24:
			formatType = GL_RGB;
			break;
		case 32:
			formatType = GL_RGBA;
			break;
		default:
			SAFE_DEL_ARRAY(src);
			glDeleteTextures(TBOCount, TBOs);
			SAFE_DEL_ARRAY(TBOs);
			return -1;
		};

		glActiveTexture(GL_TEXTURE0 + i);
		glBindTexture(GL_TEXTURE_2D, TBOs[i]);
		glTexImage2D(GL_TEXTURE_2D, 0, formatType, iWidth, iHeight, 0, formatType, GL_UNSIGNED_BYTE, src);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glGenerateMipmap(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, 0);

		SAFE_DEL_ARRAY(src);
	}

	SAFE_DEL_ARRAY_POINTER(m_fileCount, files);

	return 0;
}

FWint Texture::ImageCube()
{
	char **files = new char*[m_fileCount];
	char* temp = strtok(_strdup(m_fileName), ";");
	int i = 0;
	while (temp != NULL)
	{
		files[i] = temp;
		temp = strtok(NULL, ";");
		i++;
	}

	TBOCount = 1;
	TBOs = new FWuint[TBOCount];
	glGenTextures(1, TBOs);

	FWint iWidth, iHeight, iBPP;
	char* src = NULL;
	FWint formatType;

	glBindTexture(GL_TEXTURE_CUBE_MAP, TBOs[0]);
	for (FWuint i = 0; i < m_fileCount; i++)
	{
		std::string file = BASE_SRC_PATH + std::string(m_filePath) + std::string(files[i]);
		src = TGAImage::LoadTGA(file.c_str(), &iWidth, &iHeight, &iBPP);
		switch (iBPP)
		{
		case 24:
			formatType = GL_RGB;
			break;
		case 32:
			formatType = GL_RGBA;
			break;
		default:
			SAFE_DEL_ARRAY(src);
			glDeleteTextures(TBOCount, TBOs);
			SAFE_DEL_ARRAY(TBOs);
			return -1;
		};
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, formatType, iWidth, iHeight, 0, formatType, GL_UNSIGNED_BYTE, src);
		SAFE_DEL_ARRAY(src);
	}

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

	return 0;
}

void Texture::Destroy()
{
	glDeleteTextures(TBOCount, TBOs);
	SAFE_DEL_ARRAY(TBOs);
	SAFE_DEL_ARRAY(m_filePath);
	SAFE_DEL_ARRAY(m_fileName);
	SAFE_DEL_ARRAY(m_fileConfig);
}